Skip to content

Python: Preserve A2A response message ids#6053

Closed
he-yufeng wants to merge 2 commits into
microsoft:mainfrom
he-yufeng:fix/a2a-preserve-message-id
Closed

Python: Preserve A2A response message ids#6053
he-yufeng wants to merge 2 commits into
microsoft:mainfrom
he-yufeng:fix/a2a-preserve-message-id

Conversation

@he-yufeng
Copy link
Copy Markdown
Contributor

Summary

  • Preserve A2A message_id on streamed task status updates
  • Preserve message_id for in-progress task messages and terminal task history messages
  • Keep artifact IDs unchanged for artifact-backed updates

Closes #5949.

To verify

  • python -m py_compile python\packages\a2a\agent_framework_a2a\_agent.py python\packages\a2a\tests\test_a2a_agent.py
  • uv run pytest packages\a2a\tests\test_a2a_agent.py::test_streaming_single_working_update_with_message packages\a2a\tests\test_a2a_agent.py::test_streaming_status_update_event_yields_content packages\a2a\tests\test_a2a_agent.py::test_task_status_update_event_metadata_merged packages\a2a\tests\test_a2a_agent.py::test_history_message_metadata_propagated -q
  • uv run pytest packages\a2a\tests\test_a2a_agent.py -q
  • uv run ruff check packages\a2a\agent_framework_a2a\_agent.py packages\a2a\tests\test_a2a_agent.py
  • git diff --check

Note: uv run ruff format --check packages\a2a\agent_framework_a2a\_agent.py packages\a2a\tests\test_a2a_agent.py reports an existing formatting change in an unrelated test function signature. I left that untouched to avoid broad formatting churn.

Copilot AI review requested due to automatic review settings May 23, 2026 14:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@moonbox3
Copy link
Copy Markdown
Contributor

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/a2a/agent_framework_a2a
   _agent.py3602293%254, 262, 453, 458, 460, 513–514, 544–545, 549, 693, 709, 721, 743, 764, 811, 827, 837, 848, 855–856, 907
TOTAL36865431388% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
7385 34 💤 0 ❌ 0 🔥 1m 59s ⏱️

Copy link
Copy Markdown
Contributor

@giles17 giles17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated Code Review

Reviewers: 4 | Confidence: 93%

✓ Correctness

This PR correctly preserves A2A message IDs across three code paths: (1) terminal task history messages using an or fallback from artifact_id to message_id, (2) in-progress status messages accessed via status.message.message_id inside an existing null guard, and (3) TaskStatusUpdateEvent messages via message.message_id also within a null guard. The AgentResponseUpdate class already supports message_id, and _process_update propagates it to Message objects in AgentResponse.from_updates. No correctness issues found.

✓ Security Reliability

This PR safely propagates A2A message IDs through the response pipeline. All changes are straightforward attribute passthrough with proper null safety via getattr defaults and pre-existing null guards. No security or reliability concerns identified.

✓ Test Coverage

The PR has solid test coverage for all three production code changes. Each code path that now preserves message_id (terminal task history messages, in-progress status messages, and TaskStatusUpdateEvent messages) has at least one corresponding test with a deterministic message_id and explicit assertion. The existing test for artifact-backed updates (test_streaming_terminal_task_artifacts_are_emitted_when_terminal_event_has_no_content, line 1403) validates the priority of artifact_id in the or-fallback expression. No meaningful coverage gaps identified.

✗ Design Approach

The task-based changes look consistent, but the broader design goal in the PR title/body is still incomplete: immediate A2AMessage responses continue to lose their message_id, so only task/status responses are fixed by this approach.


Automated review by giles17's agents

@@ -727,6 +729,7 @@ def _updates_from_task_update_event(
contents=contents,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This preserves IDs for TaskStatusUpdateEvent, but the immediate A2AMessage path still drops them. In _map_a2a_stream (lines 364-373), raw A2AMessage items are converted to AgentResponseUpdate with response_id but no message_id, so _process_update never copies the ID to the resulting Message. Direct message responses created via add_message_response(...) lose their message IDs in both streaming and non-streaming modes.

@giles17
Copy link
Copy Markdown
Contributor

giles17 commented May 28, 2026

Closing in favor of #6163

@giles17 giles17 closed this May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: [A2A] Correctly Handle task_id and message_id Returned by A2A

4 participants